package cockpit.desarrollo.ConectDB;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Hashtable;

import java.util.Enumeration;
import java.util.Hashtable;

import javax.swing.text.StyledEditorKit.ForegroundAction;



public class ConnectionPool extends ObjectPool<Connection> {

  private String dsn, usr, pwd;
  private static String driverName = Constantes.DRIVERNAME;
  private static String serverName = Constantes.SERVERNAME;
  private static String portNumber = Constantes.PORTNUMBER;
  private static String squema = Constantes.SQUEMA;
  private static String mydatabase = serverName + ":" + portNumber + "/" + squema;
  private static String url = Constantes.URL + mydatabase; // a JDBC url

  public ConnectionPool(int nIniPool) {
    super();
    try {
      Class.forName(driverName).newInstance();      
      Connection [] con = new Connection [nIniPool];
              
      for( int i = 0; i < con.length; i++ )
      {
          System.out.println("creando pools iniales "+i);
          con[i]=this.checkOut();
      }
      
      for( int i = 0; i < con.length; i++ )
      {
          this.checkIn(con[i]);          
      }
      
      
      
    } catch (Exception e) {
      e.printStackTrace();
    }

  }

  @Override
  protected Connection create() {
    try {
      return (DriverManager.getConnection( url, Constantes.USER, Constantes.PASSWORD ));
    } catch (SQLException e) {
      e.printStackTrace();
      return (null);
    }
  }

  @Override
  public void expire(Connection o) {
    try {
      ((Connection) o).close();
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }

  @Override
  public boolean validate(Connection o) {
    try {
      return (!((Connection) o).isClosed());
    } catch (SQLException e) {
      e.printStackTrace();
      return (false);
    }
  }
}

abstract class ObjectPool<T> {
    private long expirationTime;

    private Hashtable<T, Long> locked, unlocked;

    public ObjectPool() {
      expirationTime = 30000; // 30 seconds
      locked = new Hashtable<T, Long>();
      unlocked = new Hashtable<T, Long>();
    }

    protected abstract T create();

    public abstract boolean validate(T o);

    public abstract void expire(T o);

    public synchronized T checkOut() {
      long now = System.currentTimeMillis();
      T t;
      if (unlocked.size() > 0) {
        Enumeration<T> e = unlocked.keys();
        while (e.hasMoreElements()) {
          t = e.nextElement();
          if ((now - unlocked.get(t)) > expirationTime) {
            // object has expired
            unlocked.remove(t);
            expire(t);
            t = null;
          } else {
            if (validate(t)) {
              unlocked.remove(t);
              locked.put(t, now);
              return (t);
            } else {
              // object failed validation
              unlocked.remove(t);
              expire(t);
              t = null;
            }
          }
        }
      }
      // no objects available, create a new one
      t = create();
      locked.put(t, now);
      return (t);
    }

    public synchronized void checkIn(T t) {
      locked.remove(t);
      unlocked.put(t, System.currentTimeMillis());
    }
  }